
import fs from "fs";
import { v4 as uuidv4 } from 'uuid';
import { Result } from "../tsgf/Result";
import { IUserInfo } from "../gateClient/UserInfo";
import { getRedisClient } from "./redisHelper";

const allConfigs: { [key: string]: any } = {};

/**
 * 开始监控配置文件,并返回读取到的配置对象
 * @param configPath 配置文件路径
 * @returns 
 */
export function startWatchConfig(configPath: string): Result<any> {
    if (allConfigs[configPath] === undefined) {
        //如果是首次启动,则开始监听
        if (!fs.existsSync(configPath)) return Result.buildErr<any>("配置文件[" + configPath + "]不存在!");
        fs.watchFile(configPath, { persistent: false, interval: 500 }, (curr, prev) => {
            allConfigs[configPath] = null;
        });
        allConfigs[configPath] = null;
    }

    return getConfig(configPath);
}
/**
 * 读取配置文件,如果配置没变更将从缓存中读取,需要调用过startWatchConfig初始化!
 * @param configPath 配置文件路径
 * @returns 
 */
export function getConfig(configPath: string): Result<any> {
    var config = allConfigs[configPath];
    if (!config) {
        let configFileText: string;
        try {
            var fileBin = fs.readFileSync(configPath);
            if (!fileBin) {
                return Result.buildErr<any>("配置文件[" + configPath + "]读取为空!可能是没权限!");
            }
            if (fileBin[0] === 0xEF && fileBin[1] === 0xBB && fileBin[2] === 0xBF) {
                fileBin = fileBin.slice(3);
            }
            configFileText=fileBin.toString('utf-8');
        } catch (ex) {
            return Result.buildErr<any>("配置文件[" + configPath + "]读取失败:" + ex);
        }
        try {
            config = JSON.parse(configFileText);
            allConfigs[configPath] = config;
        } catch (ex) {
            return Result.buildErr<any>("配置文件[" + configPath + "]解析失败:" + ex + ", configFileText:" + configFileText);
        }
    }
    return Result.buildSucc<any>(config);
}




/**
 * 分配一个游戏服务器登录令牌
 * @param gameServerId 游戏服务器ID
 * @param userInfo 要保存的用户相关信息(可json序列化的对象),验证令牌时可以获取到,不可为空,否则获取时无法判断是空还是不存在
 */
export async function allotGameLoginToken(gameServerId: string, userInfo: IUserInfo): Promise<string> {
    var gameLoginToken = uuidv4();
    var redisKey = "GameLoginToken:Server_" + gameServerId + ":" + gameLoginToken;

    await (await getRedisClient()).setObject(redisKey, userInfo, 120);

    return gameLoginToken;
}
/**
 * 验证令牌并获取用户信息
 * @param gameServerId 
 * @param gameLoginToken 
 * @returns 
 */
export async function checkGameLoginToken(gameServerId: string, gameLoginToken: string): Promise<IUserInfo> {
    var redisKey = "GameLoginToken:Server_" + gameServerId + ":" + gameLoginToken;
    var userInfo = await (await getRedisClient()).getObject(redisKey);
    return userInfo;
}